/**
 * 
 */
package OfficeServer.office;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.logging.Level;

import OfficeServer.log_error.AppointmentException;
import OfficeServer.report.Appointment;
import OfficeServer.report.Report;
import OfficeServer.users.AccessLevel;
import OfficeServer.users.User;
import OfficeServer.users.UserList;

/**
 * @author mramsey3
 * 
 */
public class AppointmentList implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private static ArrayList<Appointment> appointments = new ArrayList<Appointment>();

    private static ArrayList<Appointment> waitingAppointments = new ArrayList<Appointment>();

    public static void addAppointment(Report report, int doctorID,
	    int patientID, int day, int timeSlot) throws Exception {
	Appointment temp = new Appointment(report, doctorID, patientID, day,
		timeSlot);
	if (!appointments.contains(temp)) {
	    appointments.add(temp);
	    UserList.getPatient(patientID).addAppointment(temp);
	    UserList.getDoctor(doctorID).addAppointment(temp);
	    Calendar.getDay(day).addAppointment(temp);
	    waitingAppointments.add(temp);
	}
    }

    /**
     * @param waitingAppointments
     *            the waitingAppointments to set
     */
    public static void setWaitingAppointments(
	    ArrayList<Appointment> waitingAppointments) {
	AppointmentList.waitingAppointments = waitingAppointments;
    }

    /**
     * @return the waitingAppointments
     */
    public static ArrayList<Appointment> getWaitingAppointments() {
	return (ArrayList<Appointment>) waitingAppointments.clone();
    }

    public static void removeAppointment(Appointment temp) throws Exception {
	int patientID = temp.getPatientID();
	int doctorID = temp.getDoctorID();
	int day = temp.getDay();
	if (appointments.contains(temp)) {
	    appointments.remove(temp);
	    UserList.getPatient(patientID).removeAppointment(temp);
	    UserList.getDoctor(doctorID).removeAppointment(temp);
	    Calendar.getDay(day).removeAppointment(temp);
	    waitingAppointments.remove(temp);
	}
    }

    /**
     * @author Chris Bayruns
     * @param user
     *            The user to get appointments from
     * @return The arraylist of appointments
     */
    public static ArrayList<Appointment> getAppointmentsFromUser(User user) {
	return user.getAppointments();
    }

    /**
     * @author Chris Bayruns
     * @param day
     *            The day to get appointments from
     * @return The arraylist of appointments
     * @throws Exception
     */
    public static ArrayList<Appointment> getAppointmentsFromDay(int day)
	    throws Exception {
	return Calendar.getDay(day).getAppointments();
    }

    /**
     * @author Chris Bayruns
     * @param update
     *            The appointment to update
     * @throws Exception
     */
    public static void updatePatientAppointment(Appointment update)
	    throws Exception {
	User user = null;
	ArrayList<Appointment> list = null;
	int tempDay = 0;
	int tempDoc = 0;
	int tempSlot = 0;
	int tempPat = 0;
	boolean flag = false;
	if (update != null) {
	    for (Appointment appt : appointments) {
		if (appt.getApptID() == update.getApptID()) {
		    flag = true;
		    tempDay = appt.getDay();
		    tempDoc = appt.getDoctorID();
		    tempPat = appt.getPatientID();
		    tempSlot = appt.getTimeSlot();
		    if (appt.getDay() != update.getDay()
			    || appt.getTimeSlot() != update.getTimeSlot()
			    || appt.getDoctorID() != update.getDoctorID()) {
			Calendar.getDay(tempDay).removeAppointment(appt);
		    }
		    if (appt.getPatientID() != update.getPatientID()) {
			UserList.searchForID(tempPat, AccessLevel.PATIENT)
				.removeAppointment(appt);
		    }

		    appt.updateAppointment(update);

		    if (tempDay != update.getDay()
			    || tempSlot != update.getTimeSlot()
			    || tempDoc != update.getDoctorID()) {
			// appt.setDoctorID(tempDoc);
			Calendar.getDay(appt.getDay()).addAppointment(appt);
		    }
		    if (appt.getPatientID() != update.getPatientID()) {
			UserList.searchForID(update.getPatientID(),
				AccessLevel.PATIENT).addAppointment(appt);
		    }

		}
	    }
	    if (!flag) {
		throw (new AppointmentException(Level.INFO,
			AppointmentException.REASON.NO_APPOINTMENT, "ID: "
				+ update.getApptID()));
	    }
	} else {
	    throw (new AppointmentException(Level.INFO,
		    AppointmentException.REASON.NULL_APPOINTMENT, ""));
	}

    }

    /**
     * @author Chris Bayruns
     * @param confirm
     *            The appointment to confirm
     * @throws AppointmentException
     */
    public static void confirmAppointment(Appointment confirm)
	    throws AppointmentException {
	boolean flag = false;
	for (Appointment appt : appointments) {
	    if (appt.getApptID() == confirm.getApptID()) {
		flag = true;
		appt.setConfirmed();
		waitingAppointments.remove(confirm);
	    }
	}
	if (!flag) {
	    throw (new AppointmentException(Level.INFO,
		    AppointmentException.REASON.NO_APPOINTMENT, "ID: "
			    + confirm.getApptID()));
	}
    }

    public static ArrayList<Appointment> getAppointments() {
	return appointments;
    }

    public static void setAppointments(ArrayList<Appointment> appointmentsToSet) {
	appointments = appointmentsToSet;
    }

    public static void clear() {
	try {
	    appointments.clear();
	    waitingAppointments.clear();
	} catch (Exception e) {
	    appointments = new ArrayList<Appointment>();
	    waitingAppointments = new ArrayList<Appointment>();
	}
    }
}
